/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pt.utl.ist.isr.livetrack.ui;

import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.util.Set;
import javax.swing.Action;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.PropertySupport;
import org.openide.nodes.Sheet;
import org.openide.util.Exceptions;
import org.openide.util.HelpCtx;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;
import org.openide.util.lookup.Lookups;
import pt.utl.ist.isr.livetrack.server.LTServer;
import pt.utl.ist.isr.livetrack.server.interfaces.Zone;
import pt.utl.ist.isr.livetrack.ui.propedit.ZoneConnectionsPropertyEditor;

/**
 *
 * @author David Miguel Antunes <davidmiguel [ at ] antunes.net>
 */
public class ZoneNode extends AbstractNode implements Transferable {

    public static final DataFlavor DATA_FLAVOR = new DataFlavor(ZoneNode.class, "zone");
    private static Action[] actions = new Action[]{
        new org.openide.util.actions.SystemAction() {

            @Override
            public String getName() {
                return NbBundle.getMessage(this.getClass(), "DeleteZone");
            }

            @Override
            public HelpCtx getHelpCtx() {
                return null;
            }

            @Override
            public void actionPerformed(ActionEvent ae) {
                ZoneNode cm = Utilities.actionsGlobalContext().lookup(ZoneNode.class);
                cm.server.getPerimeter().deleteZone(cm.zone.getId());
                ZonesNodeChildFactory factory = ZonesNodeChildFactory.getFactory(cm.server);
                factory.refresh();
            }
        },};
    private LTServer server;
    private Zone zone;
    private Sheet sheet;
    private Sheet.Set set;

    public ZoneNode(LTServer server, Zone zone) {
        super(Children.LEAF, Lookups.fixed(zone, server));
        this.server = server;
        this.zone = zone;
        setDisplayName(zone.getName());
        init();
    }

    @Override
    public Image getIcon(int type) {
        return ImageUtilities.loadImage("pt/utl/ist/isr/livetrack/ui/icons/area.png", true);
    }

    @Override
    public Image getOpenedIcon(int type) {
        return getIcon(type);
    }

    private void init() {
        try {
            sheet = Sheet.createDefault();
            set = Sheet.createPropertiesSet();
            final Zone obj = getLookup().lookup(Zone.class);

            PropertySupport.Reflection conn;

            addProperties(new PropertySupport.Reflection[]{
                        new PropertySupport.Reflection(obj, String.class, "getId", null),
                        new PropertySupport.Reflection(obj, String.class, "getName", "setName"),
                        conn = new PropertySupport.Reflection(obj, Set.class, "getConnections", null),
                        new PropertySupport.Reflection(obj, boolean.class, "isEntryZone", "setEntryZone"),
                        new PropertySupport.Reflection(obj, boolean.class, "isExitZone", "setExitZone"),},
                    new String[]{
                        NbBundle.getMessage(this.getClass(), "ZoneNode_id"),
                        NbBundle.getMessage(this.getClass(), "ZoneNode_name"),
                        NbBundle.getMessage(this.getClass(), "ZoneNode_connections"),
                        NbBundle.getMessage(this.getClass(), "ZoneNode_EntryZone"),
                        NbBundle.getMessage(this.getClass(), "ZoneNode_ExitZone"),
                    });

            conn.setPropertyEditorClass(ZoneConnectionsPropertyEditor.class);

            sheet.put(set);
        } catch (NoSuchMethodException ex) {
            Exceptions.printStackTrace(ex);
        }
    }

    private void addProperties(Property[] props, String[] names) {
        for (int i = 0; i < props.length; i++) {
            Property property = props[i];
            property.setName(names[i]);
            set.put(property);
        }
    }

    @Override
    protected Sheet createSheet() {
        return sheet;
    }

    @Override
    public Action[] getActions(boolean context) {
        return actions;
    }

    @Override
    public Transferable drag() throws IOException {
        return this;
    }

    @Override
    public DataFlavor[] getTransferDataFlavors() {
        return new DataFlavor[]{ZoneNode.DATA_FLAVOR};
    }

    @Override
    public boolean isDataFlavorSupported(DataFlavor flavor) {
        return flavor == DATA_FLAVOR;
    }

    @Override
    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
        if (flavor == DATA_FLAVOR) {
            return this;
        } else {
            throw new UnsupportedFlavorException(flavor);
        }
    }

    public Zone getZone() {
        return zone;
    }

    public LTServer getServer() {
        return server;
    }
}
